from flask import Flask, request, jsonify
import hashlib
import time
import jwt

app = Flask(__name__)

# 配置
SECRET = "abcde"
DEVICE_ID = "20845"
MAX_REFRESH_COUNT = 1  # 最大刷新次数

# 模拟存储
tickets = {}
tokens = {}
refresh_counts = {}

# Helper functions
def generate_ticket(device_id):
    ticket = hashlib.md5((device_id + str(time.time())).encode('utf-8')).hexdigest()
    tickets[device_id] = ticket
    return ticket

def generate_token(device_id):
    payload = {
        "deviceId": device_id,
        "expiredTime": int(time.time()) + 3600  # 1小时过期
    }
    token = jwt.encode(payload, SECRET, algorithm="HS256")
    tokens[device_id] = token
    return token

def validate_signature(device_id, signature, ticket=None, token=None):
    if ticket:
        expected_signature = hashlib.md5((ticket + device_id + SECRET).encode('utf-8')).hexdigest()
    elif token:
        expected_signature = hashlib.md5((token + device_id + SECRET).encode('utf-8')).hexdigest()
    else:
        return False
    return signature == expected_signature

def validate_blood_pressure(data):
    try:
        high = int(data.get("high", 0))
        low = int(data.get("low", 0))
        time_str = data.get("time", "")
        if not time_str or high <= low or high < 0 or low < 0:
            return False
        return True
    except:
        return False

# Routes
@app.route('/getTicket', methods=['GET'])
def get_ticket():
    device_id = request.args.get("deviceId")
    if not device_id:
        return jsonify({"code": 201, "message": "Missing deviceId"})
    if device_id != DEVICE_ID:
        return jsonify({"code": 202, "message": "Unknown deviceId"})
    ticket = generate_ticket(device_id)
    return jsonify({"code": 200, "data": {"ticket": ticket}})

@app.route('/getToken', methods=['POST'])
def get_token():
    data = request.get_json()
    device_id = data.get("deviceId")
    signature = data.get("signature")
    ticket = data.get("ticket")
    if not all([device_id, signature, ticket]):
        return jsonify({"code": 201, "message": "Missing parameters"})
    if device_id != DEVICE_ID:
        return jsonify({"code": 202, "message": "Unknown deviceId"})
    if not validate_signature(device_id, signature, ticket=ticket):
        return jsonify({"code": 203, "message": "Invalid signature"})
    token = generate_token(device_id)
    return jsonify({"code": 200, "data": {"token": token}})

@app.route('/uploadData', methods=['POST'])
def upload_data():
    data = request.get_json()
    device_id = data.get("deviceId")
    token = data.get("token")
    blood_data = data.get("data")
    if not all([device_id, token, blood_data]):
        return jsonify({"code": 201, "message": "Missing parameters"})
    if device_id != DEVICE_ID:
        return jsonify({"code": 202, "message": "Unknown deviceId"})
    if token != tokens.get(device_id):
        return jsonify({"code": 204, "message": "Invalid token"})
    try:
        payload = jwt.decode(token, SECRET, algorithms=["HS256"])
        if payload["expiredTime"] < time.time():
            return jsonify({"code": 206, "message": "Expired token"})
    except:
        return jsonify({"code": 204, "message": "Invalid token"})
    if not validate_blood_pressure(blood_data):
        return jsonify({"code": 205, "message": "Invalid blood pressure data"})
    return jsonify({"code": 200, "data": {"receivedTime": int(time.time())}})

@app.route('/refreshToken', methods=['POST'])
def refresh_token():
    data = request.get_json()
    device_id = data.get("deviceId")
    signature = data.get("signature")
    token = data.get("token")
    if not all([device_id, signature, token]):
        return jsonify({"code": 201, "message": "Missing parameters"})
    if device_id != DEVICE_ID:
        return jsonify({"code": 202, "message": "Unknown deviceId"})
    if not validate_signature(device_id, signature, token=token):
        return jsonify({"code": 203, "message": "Invalid signature"})
    if refresh_counts.get(device_id, 0) >= MAX_REFRESH_COUNT:
        return jsonify({"code": 207, "message": "Max refresh count reached"})
    new_token = generate_token(device_id)
    refresh_counts[device_id] = refresh_counts.get(device_id, 0) + 1
    return jsonify({"code": 200, "data": {"token": new_token}})

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)